package com.ray.business.api;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ray.base.api.CustomerApi;
import com.ray.base.check.CustomerCheck;
import com.ray.base.service.BaseCustomerService;
import com.ray.base.service.compose.GoodsService;
import com.ray.base.table.entity.BaseCustomer;
import com.ray.base.table.params.customer.CustomerQueryParams;
import com.ray.base.table.vo.customer.CustomerVO;
import com.ray.base.table.vo.material.model.MaterialModelVO;
import com.ray.business.builder.BusinessBuilder;
import com.ray.business.builder.BusinessGoodsVOBuilder;
import com.ray.business.builder.BusinessVOBuilder;
import com.ray.business.builder.PrintDataBuilder;
import com.ray.business.check.*;
import com.ray.business.enums.BusinessTypeEnum;
import com.ray.business.service.*;
import com.ray.business.service.compose.BusinessService;
import com.ray.business.table.dto.BusinessPriceChangeDTO;
import com.ray.business.table.dto.BusinessQuantityDTO;
import com.ray.business.table.dto.BusinessQueryDTO;
import com.ray.business.table.dto.UserBusinessQuantityDTO;
import com.ray.business.table.entity.*;
import com.ray.business.table.params.business.*;
import com.ray.business.table.vo.BusinessGoodsVO;
import com.ray.business.table.vo.BusinessVO;
import com.ray.business.table.vo.UserBusinessQuantityVO;
import com.ray.common.check.AbstractCheck;
import com.ray.common.dto.PrintDataDTO;
import com.ray.magicBlock.BlockDispatch;
import com.ray.system.builder.CommonPageBuilder;
import com.ray.system.service.SysUserService;
import com.ray.system.service.compose.RedisService;
import com.ray.system.table.entity.SysUser;
import com.ray.template.TemplateFactory;
import com.ray.template.TemplateRecord;
import com.ray.util.CodeSplitUtil;
import com.ray.util.DateUtils;
import com.ray.validate.support.utils.ValidateUtil;
import com.ray.wms.service.WmsWarehouseService;
import com.ray.wms.table.entity.WmsWarehouse;
import com.ray.woodencreate.beans.LoginUser;
import com.ray.woodencreate.enums.YesOrNoEnum;
import com.ray.woodencreate.exception.BusinessExceptionFactory;
import com.ray.woodencreate.page.CommonPage;
import com.ray.woodencreate.result.MsgCodeConstant;
import com.ray.woodencreate.result.Result;
import com.ray.woodencreate.result.ResultFactory;
import com.ray.woodencreate.util.Assert;
import com.ray.woodencreate.util.LogInUserUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author bo shen
 * @Description: 订单相关服务
 * @Class: BusinessApi
 * @Package com.ray.base.api
 * @date 2020/5/27 11:15
 * @company <p>Ray快速开发平台</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
@Service
@Slf4j
public class BusinessApi {

    @Autowired
    private ProdStepService prodStepService;
    @Autowired
    private BaseCustomerService baseCustomerService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private ProdOrderStepService prodOrderStepService;
    @Autowired
    private ProdBusinessOutService prodBusinessOutService;
    @Autowired
    private ProdBusinessService prodBusinessService;
    @Autowired
    private ProdOrderService prodOrderService;
    @Autowired
    private WmsWarehouseService wmsWarehouseService;
    @Autowired
    private ProdOrderGoodsService prodOrderGoodsService;
    @Autowired
    private BlockDispatch<BusinessQueryDTO, LoginUser, List<BusinessGoodsVO>> blockDispatch;
    @Autowired
    private BlockDispatch<BusinessCreateParams, LoginUser, String> createDispatch;
    @Autowired
    private BlockDispatch<BusinessEditParams, LoginUser, String> editDispatch;
    @Autowired
    private BlockDispatch<ProdBusiness, LoginUser, String> commonDispatch;
    @Autowired
    private BlockDispatch<ProdBusiness, LoginUser, BusinessVO> viewDispatch;
    @Autowired
    private CustomerApi customerApi;
    @Autowired
    private ProdBusinessBackService prodBusinessBackService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private BusinessService businessService;
    @Autowired
    private ProdBusinessInService prodBusinessInService;

    /**
     * 查询订单列表信息 分页  非删除的
     *
     * @param queryParams
     * @return
     */
    public Result<IPage<BusinessVO>> pageBusinesss(CommonPage<BusinessQueryParams, Page<BusinessVO>> queryParams) {
        Assert.notNull(queryParams, "参数[queryParams]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        Map<String, BaseCustomer> baseCustomerMap = new HashMap<>();
        Map<String, WmsWarehouse> wmsWarehouseMap = new HashMap<>();
        Map<String, MaterialModelVO> modelMap = new HashMap<>();
        Map<String, ProdStep> stepMap = new HashMap<>();
        CommonPageBuilder<BusinessQueryDTO, ProdBusiness> commonPageBuilder = new CommonPageBuilder<>(BusinessQueryDTO.class);
        commonPageBuilder.appendEntity(queryParams.getEntity()).appendQuery(queryParams.getQuery()).appendPage(queryParams.getPage());
        IPage<ProdBusiness> page = prodBusinessService.page(commonPageBuilder.bulid(), loginUser);
        List<ProdBusiness> orders = page.getRecords();
        //结果对象
        IPage<BusinessVO> pageList = new Page<>();
        pageList.setTotal(page.getTotal());
        pageList.setCurrent(page.getCurrent());
        pageList.setSize(page.getSize());
        //查询到结果 数据转换
        if (ObjectUtil.isNotNull(orders)) {
            pageList.setRecords(orders.stream().map(sysBusiness -> {
                //查询客信息
                BaseCustomer baseCustomer = baseCustomerMap.get(sysBusiness.getCustomerCode());
                if (ObjectUtil.isEmpty(baseCustomer)) {
                    baseCustomer = baseCustomerService.queryCustomerByCustomerCode(sysBusiness.getCustomerCode(), loginUser);
                    baseCustomerMap.put(sysBusiness.getCustomerCode(), baseCustomer);
                }
                //查询仓库信息
                WmsWarehouse wmsWarehouse = wmsWarehouseMap.get(sysBusiness.getWarehouseCode());
                if (ObjectUtil.isEmpty(wmsWarehouse)) {
                    wmsWarehouse = wmsWarehouseService.queryWarehouseByWarehouseCode(sysBusiness.getWarehouseCode(), loginUser);
                    wmsWarehouseMap.put(wmsWarehouse.getWarehouseCode(), wmsWarehouse);
                }
                //工序信息
                ProdStep prodStep = stepMap.get(sysBusiness.getStepCode());
                if (ObjectUtil.isEmpty(prodStep)) {
                    prodStep = prodStepService.queryStepByStepCode(sysBusiness.getStepCode(), loginUser);
                    stepMap.put(sysBusiness.getStepCode(), prodStep);
                }
                MaterialModelVO materialModelVO = modelMap.get(sysBusiness.getGoodsCode());
                if (ObjectUtil.isNull(materialModelVO)) {
                    materialModelVO = goodsService.queryGoodsByCode(sysBusiness.getGoodsCode(), loginUser);
                    modelMap.put(sysBusiness.getGoodsCode(), materialModelVO);
                }
                return new BusinessVOBuilder().append(sysBusiness).append(baseCustomer).append(wmsWarehouse)
                        .append(prodStep).append(materialModelVO).bulid();
            }).collect(Collectors.toList()));
        } else {
            pageList.setRecords(new ArrayList<>());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, pageList);
    }


    /**
     * 查询订单可以出库的列表
     *
     * @param businessQueryParams
     * @return
     */
    public Result<List<BusinessGoodsVO>> listOutGoods(BusinessQueryParams businessQueryParams) {
        Assert.notNull(businessQueryParams, "参数[businessQueryParams]不能为空");
        ValidateUtil.validate(businessQueryParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //步骤第一个订单的出库物料获取
        String strategy = "order";
        //查询步骤顺序
        ProdOrderStep prodOrderStep = prodOrderStepService.queryStepByStepCode(CodeSplitUtil.getFirst(businessQueryParams.getGoodsCode()), businessQueryParams.getStepCode(), loginUser);
        new OrderStepCheck(prodOrderStep).checkNull("订单配置步骤数据不存在");
        if (prodOrderStep.getIndexSort() != 1) {
            strategy = "step";
        }
        BusinessQueryDTO businessQueryDTO = new BusinessQueryDTO();
        BeanUtil.copyProperties(businessQueryParams, businessQueryDTO);
        businessQueryDTO.setOrderStep(prodOrderStep);
        List<BusinessGoodsVO> goodsVOS = blockDispatch.dispatch("outGoods", strategy, businessQueryDTO, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, goodsVOS);
    }

    /**
     * 查询订单可以出库的列表
     *
     * @param businessQueryParams
     * @return
     */
    public Result<List<BusinessGoodsVO>> listBackOutGoods(BusinessQueryParams businessQueryParams) {
        Assert.notNull(businessQueryParams, "参数[businessQueryParams]不能为空");
        ValidateUtil.validate(businessQueryParams);
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        String strategy = "stepBack";
        //查询步骤顺序
        ProdOrderStep thisStep = prodOrderStepService.queryStepByStepCode(CodeSplitUtil.getFirst(businessQueryParams.getGoodsCode()), businessQueryParams.getStepCode(), loginUser);
        new OrderStepCheck(thisStep).checkNull("订单配置步骤数据不存在");
        BusinessQueryDTO businessQueryDTO = new BusinessQueryDTO();
        BeanUtil.copyProperties(businessQueryParams, businessQueryDTO);
        businessQueryDTO.setOrderStep(thisStep);
        List<BusinessGoodsVO> goodsVOS = blockDispatch.dispatch("outGoods", strategy, businessQueryDTO, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, goodsVOS);
    }


    /**
     * 查询订单可以入库的列表
     *
     * @param businessQueryParams
     * @return
     */
    public Result<List<BusinessGoodsVO>> listInGoods(BusinessQueryParams businessQueryParams) {
        Assert.notNull(businessQueryParams, "参数[businessQueryParams]不能为空");
        Assert.hasLength(businessQueryParams.getCustomerCode(), "请选择客户");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //查询步骤顺序
        ProdOrderStep prodOrderStep = prodOrderStepService.queryStepByStepCode(CodeSplitUtil.getFirst(businessQueryParams.getGoodsCode()), businessQueryParams.getStepCode(), loginUser);
        new OrderStepCheck(prodOrderStep).checkNull("订单配置步骤数据不存在");
        //查询步骤
        ProdStep prodStep = prodStepService.queryStepByStepCode(businessQueryParams.getStepCode(), loginUser);
        new StepCheck(prodStep).checkNull("工序不存在");
        //查询订单商品
        MaterialModelVO goodsModelVo = goodsService.queryGoodsByCode(businessQueryParams.getGoodsCode(), loginUser);
        new AbstractCheck<>(goodsModelVo).checkNull("订单商品不存在");
        //查询订单对应的加工单
        List<ProdBusiness> prodBusinesses = prodBusinessService.listByOrderNo(businessQueryParams.getOrderNo(), businessQueryParams.getStepCode(),
                businessQueryParams.getCustomerCode(), businessQueryParams.getGoodsCode(), loginUser);
        if (ObjectUtil.isNotEmpty(prodBusinesses)) {
            //查询
            List<String> businessCodes = prodBusinesses.stream().map(ProdBusiness::getBusinessCode).collect(Collectors.toList());
            //查询出库单信息
            List<BusinessGoodsVO> prodPurchaseRecords = prodBusinessOutService.list(businessCodes, loginUser)
                    .stream().filter(prodBusinessOut -> {
                        return prodBusinessOut.getQuantity().compareTo(BigDecimal.ZERO) > 0;
                    }).map(prodBusinessOut -> {
                        //查询商品详情
                        MaterialModelVO modelVO = null;
                        Boolean appendUnit = false;
                        if (prodStep.getGoodsStatus() == YesOrNoEnum.YES.getValue().intValue()) {
                            modelVO = goodsModelVo;
                            appendUnit = true;
                        } else {
                            //工序是产品变化
                            modelVO = goodsService.queryGoodsByCode(prodBusinessOut.getGoodsCode(), loginUser);
                        }
                        //商品构建
                        BusinessGoodsVOBuilder businessGoodsVOBuilder = new BusinessGoodsVOBuilder()
                                .append(modelVO).append(prodBusinessOut)
                                .appendGoodsCode(modelVO.getModelCode());
                        if(appendUnit){
                            businessGoodsVOBuilder.appendUnit(modelVO.getUnit());
                        }
                        return businessGoodsVOBuilder.bulid();
                    }).collect(Collectors.toList());
            return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, prodPurchaseRecords);
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, new ArrayList<>());
    }

    /**
     * 创建加工业务入库单
     *
     * @return
     */
    @Transactional
    public Result<String> createBusinessIn(BusinessCreateParams createParams) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //判断订单是否存在
        ProdOrder prodOrder = prodOrderService.queryOrderByOrderCode(createParams.getOrderNo(), loginUser);
        new OrderCheck(prodOrder).checkNull("订单数据不存在").checkProd("订单状态未审批通过");
        //判断客户是否存在
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerCode(createParams.getCustomerCode(), loginUser);
        new CustomerCheck(baseCustomer).checkNull(String.format("%s未查询到客户", createParams.getCustomerCode()));
        //商品是否存在
        ProdOrderGoods prodOrderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(prodOrder.getOrderNo(), createParams.getGoodsCode(), loginUser);
        new OrderGoodsCheck(prodOrderGoods).checkNull("商品不属于该订单");
        String businessCode = createDispatch.dispatch("createBusiness", "in", createParams, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);

    }


    /**
     * 创建加工业务出库单
     *
     * @return
     */
    @Transactional
    public Result<String> createBusinessOut(BusinessCreateParams createParams) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        //判断订单是否存在
        ProdOrder prodOrder = prodOrderService.queryOrderByOrderCode(createParams.getOrderNo(), loginUser);
        new OrderCheck(prodOrder).checkNull("订单数据不存在").checkProd("订单状态未安排生产");
        //判断客户是否存在
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerCode(createParams.getCustomerCode(), loginUser);
        new CustomerCheck(baseCustomer).checkNull(String.format("%s未查询到客户", createParams.getCustomerCode()));
        //商品是否存在
        ProdOrderGoods prodOrderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(prodOrder.getOrderNo(), createParams.getGoodsCode(), loginUser);
        new OrderGoodsCheck(prodOrderGoods).checkNull("商品不属于该订单");
        String businessCode = createDispatch.dispatch("createBusiness", "out", createParams, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }

    /**
     * 编辑加工业务出库单
     *
     * @return
     */
    @Transactional
    public Result<String> editBusiness(BusinessEditParams editParams) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(editParams.getBusinessCode(), loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkCanEdit("订单不能编辑");
        //判断订单是否存在
        ProdOrder prodOrder = prodOrderService.queryOrderByOrderCode(editParams.getOrderNo(), loginUser);
        new OrderCheck(prodOrder).checkNull("订单数据不存在").checkProd("订单状态未审批通过");
        //判断客户是否存在
        BaseCustomer baseCustomer = baseCustomerService.queryCustomerByCustomerCode(editParams.getCustomerCode(), loginUser);
        new CustomerCheck(baseCustomer).checkNull(String.format("%s未查询到客户", editParams.getCustomerCode()));
        //商品是否存在
        ProdOrderGoods prodOrderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(prodOrder.getOrderNo(), editParams.getGoodsCode(), loginUser);
        new OrderGoodsCheck(prodOrderGoods).checkNull("商品不属于该订单");
        String businessCode = editDispatch.dispatch("editBusiness", business.getBusinessType().toLowerCase(), editParams, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }


    /**
     * 删除
     *
     * @return
     */
    @Transactional
    public Result<String> deleteBusiness(String businessCode) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkCanDelete("订单不能删除");
        //删除业务单
        commonDispatch.dispatch("deleteBusiness", business.getBusinessType().toLowerCase(), business, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }


    /**
     * 审核
     *
     * @return
     */
    @Transactional
    public Result<String> passBusiness(String businessCode) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkCanCheck("订单已审核");
        //审核业务单
        commonDispatch.dispatch("passBusiness", business.getBusinessType().toLowerCase(), business, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }

    /**
     * 审核
     *
     * @return
     */
    @Transactional
    public Result<String> finishBusiness(String businessCode) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkNotFinish("订单还未完成").checkOutType("只有出库加工单才能操作");
        BusinessBuilder businessBuilder = new BusinessBuilder();
        businessBuilder.appendCode(businessCode).appendEdit(loginUser).appendStatus(YesOrNoEnum.YES.getValue());
        //更新
        prodBusinessService.edit(businessBuilder.bulid(), loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }

    /**
     * 审核
     *
     * @return
     */
    @Transactional
    public Result<String> openBusiness(String businessCode) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkNotFinish("订单还未完成").checkOutType("只有出库加工单才能操作");
        BusinessBuilder businessBuilder = new BusinessBuilder();
        businessBuilder.appendCode(businessCode).appendEdit(loginUser).appendStatus(YesOrNoEnum.NO.getValue());
        //更新
        prodBusinessService.edit(businessBuilder.bulid(), loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }

    /**
     * 取消
     *
     * @return
     */
    @Transactional
    public Result<String> cancelBusiness(String businessCode) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkCanCancel("订单不能取消");
        //查询是否有退料单没有取消
        int backCount = prodBusinessBackService.countUseByBusinessCode(businessCode, loginUser);
        if (backCount > 0) {
            log.info("加工单有:{}条对账单为取消", backCount);
            throw BusinessExceptionFactory.newException("有未取消的退料单");
        }
        //取消业务单
        commonDispatch.dispatch("cancelBusiness", business.getBusinessType().toLowerCase(), business, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessCode);
    }


    /**
     * 取消
     *
     * @return
     */
    public Result<BusinessVO> viewBusiness(String businessCode, String businessType) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(businessCode, loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkBusinessType(businessType, "出入库类型不一致");
        //业务单详情
        BusinessVO businessVO = viewDispatch.dispatch("viewBusiness", business.getBusinessType().toLowerCase(), business, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessVO);
    }

    /**
     * 入库客户列表
     *
     * @param queryParams
     * @return
     */
    public Result<List<CustomerVO>> listCustomer(BusinessQueryParams queryParams) {
        LoginUser loginUser = LogInUserUtil.get();
        //查询当前出库单
        List<ProdBusiness> prodBusinesses = prodBusinessService.listOutByOrderNoAndSetpCode(queryParams.getOrderNo(), queryParams.getStepCode(), loginUser);
        if (ObjectUtil.isEmpty(prodBusinesses)) {
            return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, new ArrayList<>());
        }
        List<String> customerCodes = prodBusinesses.stream().map(ProdBusiness::getCustomerCode).collect(Collectors.toList());
        CustomerQueryParams customerQueryParams = new CustomerQueryParams();
        customerQueryParams.setCustomerCodes(customerCodes);
        return customerApi.queryCustomers(customerQueryParams);
    }

    /**
     * 获取订单
     *
     * @param queryParams
     * @return
     */
    public Result<List<MaterialModelVO>> listGoods(@Valid BusinessQueryParams queryParams) {
        LoginUser loginUser = LogInUserUtil.get();
        MaterialModelVO materialModelVO = goodsService.queryGoodsByCode(queryParams.getGoodsCode(), loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, Arrays.asList(materialModelVO));
    }


    /**
     * 查询订单可以出库的列表
     *
     * @param businessQueryParams
     * @return
     */
    public Result<List<BusinessVO>> listQuickBusiness(BusinessQueryParams businessQueryParams) {
        Assert.notNull(businessQueryParams, "参数[businessQueryParams]不能为空");
        ValidateUtil.validate(businessQueryParams);
        LoginUser loginUser = LogInUserUtil.get();
        //查询订单工序
        BusinessQueryDTO businessQueryDTO = new BusinessQueryDTO();
        BeanUtil.copyProperties(businessQueryParams, businessQueryDTO);
        Map<String, BaseCustomer> baseCustomerMap = new HashMap<>();
        Map<String, WmsWarehouse> wmsWarehouseMap = new HashMap<>();
        Map<String, ProdStep> stepMap = new HashMap<>();
        //查询支持会计入库的工序
        List<String> stepCodes = prodStepService.listQuick(loginUser).stream().map(ProdStep::getStepCode).collect(Collectors.toList());
        List<ProdBusiness> businesses = prodBusinessService.listOutGroupStep(businessQueryDTO,stepCodes, loginUser);
        List<BusinessVO> businessVOS = businesses.stream().map(sysBusiness -> {
            //查询客信息
            BaseCustomer baseCustomer = baseCustomerMap.get(sysBusiness.getCustomerCode());
            if (ObjectUtil.isEmpty(baseCustomer)) {
                baseCustomer = baseCustomerService.queryCustomerByCustomerCode(sysBusiness.getCustomerCode(), loginUser);
                baseCustomerMap.put(sysBusiness.getCustomerCode(), baseCustomer);
            }
            //查询仓库信息
            WmsWarehouse wmsWarehouse = wmsWarehouseMap.get(sysBusiness.getWarehouseCode());
            if (ObjectUtil.isEmpty(wmsWarehouse)) {
                wmsWarehouse = wmsWarehouseService.queryWarehouseByWarehouseCode(sysBusiness.getWarehouseCode(), loginUser);
                wmsWarehouseMap.put(wmsWarehouse.getWarehouseCode(), wmsWarehouse);
            }
            //查询商品信息
            MaterialModelVO materialModelVO = goodsService.queryGoodsByCode(sysBusiness.getGoodsCode(), loginUser);
            //工序信息
            ProdStep prodStep = stepMap.get(sysBusiness.getStepCode());
            if (ObjectUtil.isEmpty(prodStep)) {
                prodStep = prodStepService.queryStepByStepCode(sysBusiness.getStepCode(), loginUser);
                stepMap.put(sysBusiness.getStepCode(), prodStep);
            }
            //查询订单的工序
            ProdOrderStep prodOrderStep = prodOrderStepService.queryStepByStepCode(CodeSplitUtil.getFirst(sysBusiness.getGoodsCode()), sysBusiness.getStepCode(), loginUser);
            return new BusinessVOBuilder().append(baseCustomer).append(wmsWarehouse).append(prodStep).append(materialModelVO)
                    .append(prodOrderStep).append(sysBusiness).bulid();
        }).collect(Collectors.toList());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessVOS);
    }

    /**
     * 员工馋了统计  当时间为空查询当前一年的数据
     *
     * @param quantityQueryParams
     * @return
     */
    public Result<List<UserBusinessQuantityVO>> businessQuantityCount(BusinessQuantityQueryParams quantityQueryParams) {
        LoginUser loginUser = LogInUserUtil.get();

        UserBusinessQuantityDTO userBusinessQuantityDTO = new UserBusinessQuantityDTO();
        //获取开始时间和结束时间
        if (ObjectUtil.isNull(quantityQueryParams.getMonth())) {
            //获取今年开始时间和结束时间
            userBusinessQuantityDTO.setStartTime(DateUtils.toLocalDateTime(DateUtil.beginOfYear(new Date())));
            userBusinessQuantityDTO.setEndTime(DateUtils.toLocalDateTime(DateUtil.endOfYear(new Date())));
        } else {
            //获取本月开始时间和结束时间
            userBusinessQuantityDTO.setStartTime(DateUtils.toLocalDateTime(DateUtil.beginOfMonth(quantityQueryParams.getMonth())));
            userBusinessQuantityDTO.setEndTime(DateUtils.toLocalDateTime(DateUtil.endOfMonth(quantityQueryParams.getMonth())));
        }
        userBusinessQuantityDTO.setCompanyCode(loginUser.getCompanyCode());
        userBusinessQuantityDTO.setUserProp("employee");
        //统计数据
        List<BusinessQuantityDTO> employeeQuantity = prodBusinessService.quantityCount(userBusinessQuantityDTO);
        userBusinessQuantityDTO.setUserProp("employeea");
        //统计数据 a
        List<BusinessQuantityDTO> employeeaQuantity = prodBusinessService.quantityCount(userBusinessQuantityDTO);

        Map<String, BigDecimal> userQuantity = new HashMap<>();
        employeeQuantity.stream().forEach(businessQuantityDTO -> {
            userQuantity.put(businessQuantityDTO.getUserCode(), businessQuantityDTO.getQuantity());
        });
        employeeaQuantity.stream().forEach(businessQuantityDTO -> {
            BigDecimal quantity = userQuantity.get(businessQuantityDTO.getUserCode());
            if (ObjectUtil.isNull(quantity)) {
                quantity = BigDecimal.ZERO;
            }
            quantity = quantity.add(businessQuantityDTO.getQuantity());
            userQuantity.put(businessQuantityDTO.getUserCode(), quantity);
        });

        //转成需要的结果
        List<UserBusinessQuantityVO> businessQuantityVOS = userQuantity.entrySet().stream().map(entity -> {
            UserBusinessQuantityVO userBusinessQuantityVO = new UserBusinessQuantityVO();
            userBusinessQuantityVO.setQuantity(entity.getValue());
            userBusinessQuantityVO.setUserCode(entity.getKey());
            //查询用户信息
            SysUser sysUser = sysUserService.queryUserByUserCode(entity.getKey(), loginUser);
            if (ObjectUtil.isNotNull(sysUser)) {
                userBusinessQuantityVO.setUserName(sysUser.getUserName());
            }
            return userBusinessQuantityVO;
        }).sorted((a, b) -> {
            return NumberUtil.null2Zero(b.getQuantity()).compareTo(NumberUtil.null2Zero(a.getQuantity()));
        }).collect(Collectors.toList());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessQuantityVOS);
    }

    /**
     * 获取唯一序列号
     *
     * @return
     */
    public Result<String> getNumber() {
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, businessService.getNumber());
    }


    /**
     * 更改加工单价
     *
     * @return
     */
    @Transactional
    public Result<String> changePrice(BusinessPriceChangeParams changeParams) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusiness business = prodBusinessService.queryBusinessByBusinessCode(changeParams.getBusinessCode(), loginUser);
        new BusinessCheck(business).checkNull("业务加工单不存在").checkBusinessType(BusinessTypeEnum.IN.getValue(), "入库单才能修改")
                .canDeleteDeduction("加工单已对账");
        BusinessPriceChangeDTO businessPriceChangeDTO = new BusinessPriceChangeDTO();
        businessPriceChangeDTO.setBusinessCode(changeParams.getBusinessCode());
        businessPriceChangeDTO.setPrice(changeParams.getPrice());
        businessPriceChangeDTO.setUpdateVersion(business.getUpdateVersion());
        prodBusinessService.updateQuantityPrice(businessPriceChangeDTO, loginUser);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, changeParams.getBusinessCode());
    }

    /**
     * 查询序列号对应的
     *
     * @param queryParams
     * @return
     */
    public Result<List<BusinessGoodsVO>> getBusinessGoods(NumberQueryParams queryParams) {
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        List<BusinessGoodsVO> goodsVOS = new ArrayList<>();
        Map<String, BaseCustomer> baseCustomerMap = new HashMap<>();
        Map<String, ProdStep> stepMap = new HashMap<>();
        //查询出库数据
        List<ProdBusinessOut> outs = prodBusinessOutService.listByNumber(queryParams.getSerialNumber(), loginUser);
        goodsVOS.addAll(outs.parallelStream().map(prodBusinessOut -> {
            //查询加工单号
            ProdBusiness prodBusiness = prodBusinessService.queryBusinessByBusinessCode(prodBusinessOut.getBusinessCode(), loginUser);
            //查询客信息
            BaseCustomer baseCustomer = baseCustomerMap.get(prodBusiness.getCustomerCode());
            if (ObjectUtil.isEmpty(baseCustomer)) {
                baseCustomer = baseCustomerService.queryCustomerByCustomerCode(prodBusiness.getCustomerCode(), loginUser);
                baseCustomerMap.put(prodBusiness.getCustomerCode(), baseCustomer);
            }

            //工序信息
            ProdStep prodStep = stepMap.get(prodBusiness.getStepCode());
            if (ObjectUtil.isEmpty(prodStep)) {
                prodStep = prodStepService.queryStepByStepCode(prodBusiness.getStepCode(), loginUser);
                stepMap.put(prodBusiness.getStepCode(), prodStep);
            }
            MaterialModelVO modelVO = goodsService.queryGoodsByCode(prodBusinessOut.getGoodsCode(), loginUser);
            //商品构建
            BusinessGoodsVO businessGoodsVO = new BusinessGoodsVOBuilder()
                    .append(modelVO).append(prodBusinessOut)
                    .appendUnit(modelVO.getUnit())
                    .appendGoodsCode(modelVO.getModelCode()).append(prodStep).append(baseCustomer)
                    .appendType("出库").bulid();
            return businessGoodsVO;
        }).collect(Collectors.toList()));
        //查询入库数据
        List<ProdBusinessIn> ins = prodBusinessInService.listByNumber(queryParams.getSerialNumber(), loginUser);
        goodsVOS.addAll(ins.parallelStream().map(prodBusinessIn -> {
            //查询加工单号
            ProdBusiness prodBusiness = prodBusinessService.queryBusinessByBusinessCode(prodBusinessIn.getBusinessCode(), loginUser);
            //查询客信息
            BaseCustomer baseCustomer = baseCustomerMap.get(prodBusiness.getCustomerCode());
            if (ObjectUtil.isEmpty(baseCustomer)) {
                baseCustomer = baseCustomerService.queryCustomerByCustomerCode(prodBusiness.getCustomerCode(), loginUser);
                baseCustomerMap.put(prodBusiness.getCustomerCode(), baseCustomer);
            }
            //工序信息
            ProdStep prodStep = stepMap.get(prodBusiness.getStepCode());
            if (ObjectUtil.isEmpty(prodStep)) {
                prodStep = prodStepService.queryStepByStepCode(prodBusiness.getStepCode(), loginUser);
                stepMap.put(prodBusiness.getStepCode(), prodStep);
            }
            MaterialModelVO modelVO = goodsService.queryGoodsByCode(prodBusinessIn.getGoodsCode(), loginUser);
            //商品构建
            BusinessGoodsVO businessGoodsVO = new BusinessGoodsVOBuilder()
                    .append(modelVO).append(prodBusinessIn)
                    .appendUnit(modelVO.getUnit())
                    .appendGoodsCode(modelVO.getModelCode())
                    .append(prodStep).append(baseCustomer)
                    .appendType("入库").bulid();
            return businessGoodsVO;
        }).collect(Collectors.toList()));
        //排序
        goodsVOS.sort(Comparator.comparingLong(goodsVO -> {
            if (ObjectUtil.isNotNull(goodsVO.getCreateTime())) {
                return goodsVO.getCreateTime().atZone(ZoneId.systemDefault()).toEpochSecond();
            }
            return 0;
        }));
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, goodsVOS);
    }


    /**
     * 查询序列号对应的
     *
     * @param businessCode
     * @return
     */
    public Result<List<BusinessGoodsVO>> businessInGoods(String businessCode) {
        Assert.hasLength(businessCode, "参数[businessCode]不能为空");
        //当前登录对象
        LoginUser loginUser = LogInUserUtil.get();
        Map<String, MaterialModelVO> modelMap = new HashMap<>();
        List<BusinessGoodsVO> goodsVOS = prodBusinessInService.listAll(businessCode,loginUser)
                .stream().map(prodBusinessIn -> {
                    BusinessGoodsVOBuilder businessGoodsVOBuilder = new BusinessGoodsVOBuilder();
                    MaterialModelVO materialModelVO = modelMap.get(prodBusinessIn.getGoodsCode());
                    if (ObjectUtil.isNull(materialModelVO)) {
                        materialModelVO = goodsService.queryGoodsByCode(prodBusinessIn.getGoodsCode(), loginUser);
                        modelMap.put(prodBusinessIn.getGoodsCode(),materialModelVO);
                    }
                    businessGoodsVOBuilder.append(materialModelVO);
                    businessGoodsVOBuilder.append(prodBusinessIn);
                    return businessGoodsVOBuilder.bulid();
                }).collect(Collectors.toList());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, goodsVOS);
    }

    /**
     * 入库单信息
     * @param businessCode
     * @return
     */
    public Result<List<List<TemplateRecord>>> printBusinessData(String businessCode) {
        ValidateUtil.hasLength(businessCode,"参数不能为空");
        LoginUser loginUser = LogInUserUtil.get();
        List<ProdBusinessIn> businessIns = prodBusinessInService.listAll(businessCode,loginUser);
        //数据转换
        List<List<TemplateRecord>> list = businessIns.stream().map(businessIn -> {
            //查询商品信息
            MaterialModelVO materialModelVO = goodsService.queryGoodsByCode(businessIn.getGoodsCode(), loginUser);
            //查询订单商品信息
            ProdOrderGoods prodOrderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(businessIn.getOrderNo(), businessIn.getGoodsCode(), loginUser);
            //打印对象信息
            PrintDataDTO printDataDTO = new PrintDataBuilder().append(materialModelVO).append(businessIn).append(prodOrderGoods).bulid();
            List<TemplateRecord> records = new TemplateFactory<>().readTemplate(printDataDTO);
            return  records;
        }).collect(Collectors.toList());
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, list);
    }

    /**
     * 入库单信息
     * @param code
     * @return
     */
    public Result<List<TemplateRecord>> printData(String code) {
        ValidateUtil.hasLength(code,"参数不能为空");
        LoginUser loginUser = LogInUserUtil.get();
        ProdBusinessIn businessIn = prodBusinessInService.getUsableGoodsByCode(code,loginUser);
        //查询商品信息
        MaterialModelVO materialModelVO = goodsService.queryGoodsByCode(businessIn.getGoodsCode(), loginUser);
        //查询订单商品信息
        ProdOrderGoods prodOrderGoods = prodOrderGoodsService.queryOrderGoodsByGoodsCode(businessIn.getOrderNo(), businessIn.getGoodsCode(), loginUser);
        //打印对象信息
        PrintDataDTO printDataDTO = new PrintDataBuilder().append(materialModelVO).append(businessIn).append(prodOrderGoods).bulid();
        List<TemplateRecord> records = new TemplateFactory<>().readTemplate(printDataDTO);
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000001, records);
    }

    /**
     * 批量获取序列号
     *
     * @param quantity
     * @return
     */
    public Result<List<String>> getNumbers(Integer quantity) {
        Assert.notNull(quantity, "数量不能为空");
        List<String> list = new ArrayList<>();
        for (int i = 0; i < quantity; i++) {
            list.add(businessService.getNumber());
        }
        return ResultFactory.createSuccessResult(MsgCodeConstant.Success.SUC00000002, list);
    }
}
